<!DOCTYPE html>
<html class="writer-html5" lang="en" data-content_root="../">
<head>
  <meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" />

  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Multi-threading programming &mdash; The Logtalk Handbook v3.93.0-b01 documentation</title>
      <link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=d75fae25" />
      <link rel="stylesheet" type="text/css" href="../_static/css/theme.css?v=19f00094" />
      <link rel="stylesheet" type="text/css" href="../_static/css/custom.css?v=396eccfe" />

  
  <!--[if lt IE 9]>
    <script src="../_static/js/html5shiv.min.js"></script>
  <![endif]-->
  
        <script src="../_static/jquery.js?v=5d32c60e"></script>
        <script src="../_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
        <script src="../_static/documentation_options.js?v=c8100655"></script>
        <script src="../_static/doctools.js?v=9a2dae69"></script>
        <script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
    <script src="../_static/js/theme.js"></script>
    <!-- begin favicon -->
    <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
    <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
    <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
    <link rel="manifest" href="/site.webmanifest" />
    <link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5" />
    <meta name="msapplication-TileColor" content="#355b95" />
    <meta name="theme-color" content="#ffffff" />
    <!-- end favicon -->
    
    <link rel="index" title="Index" href="../genindex.html" />
    <link rel="search" title="Search" href="../search.html" />
    <link rel="next" title="Error handling" href="errors.html" />
    <link rel="prev" title="Event-driven programming" href="events.html" />
   
</head>

<body class="wy-body-for-nav"> 
  <div class="wy-grid-for-nav">
    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
      <div class="wy-side-scroll">
        <div class="wy-side-nav-search" >

          
          
          <a href="../index.html" class="icon icon-home">
            The Logtalk Handbook
              <img src="../_static/logtalk.gif" class="logo" alt="Logo"/>
          </a>
              <div class="version">
                3.93.0
              </div>
<div role="search">
  <form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
    <input type="text" name="q" placeholder="Search docs" aria-label="Search docs" />
    <input type="hidden" name="check_keywords" value="yes" />
    <input type="hidden" name="area" value="default" />
  </form>
</div>
        </div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
    
              <p class="caption" role="heading"><span class="caption-text">Contents</span></p>
<ul class="current">
<li class="toctree-l1 current"><a class="reference internal" href="index.html">User Manual</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="declarative.html">Declarative object-oriented programming</a></li>
<li class="toctree-l2"><a class="reference internal" href="features.html">Main features</a></li>
<li class="toctree-l2"><a class="reference internal" href="nomenclature.html">Nomenclature</a></li>
<li class="toctree-l2"><a class="reference internal" href="messages.html">Messages</a></li>
<li class="toctree-l2"><a class="reference internal" href="objects.html">Objects</a></li>
<li class="toctree-l2"><a class="reference internal" href="protocols.html">Protocols</a></li>
<li class="toctree-l2"><a class="reference internal" href="categories.html">Categories</a></li>
<li class="toctree-l2"><a class="reference internal" href="predicates.html">Predicates</a></li>
<li class="toctree-l2"><a class="reference internal" href="inheritance.html">Inheritance</a></li>
<li class="toctree-l2"><a class="reference internal" href="events.html">Event-driven programming</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">Multi-threading programming</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#enabling-multi-threading-support">Enabling multi-threading support</a></li>
<li class="toctree-l3"><a class="reference internal" href="#enabling-objects-to-make-multi-threading-calls">Enabling objects to make multi-threading calls</a></li>
<li class="toctree-l3"><a class="reference internal" href="#multi-threading-built-in-predicates">Multi-threading built-in predicates</a><ul>
<li class="toctree-l4"><a class="reference internal" href="#proving-goals-concurrently-using-threads">Proving goals concurrently using threads</a></li>
<li class="toctree-l4"><a class="reference internal" href="#proving-goals-asynchronously-using-threads">Proving goals asynchronously using threads</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="#one-way-asynchronous-calls">One-way asynchronous calls</a></li>
<li class="toctree-l3"><a class="reference internal" href="#asynchronous-calls-and-synchronized-predicates">Asynchronous calls and synchronized predicates</a></li>
<li class="toctree-l3"><a class="reference internal" href="#synchronizing-threads-through-notifications">Synchronizing threads through notifications</a></li>
<li class="toctree-l3"><a class="reference internal" href="#threaded-engines">Threaded engines</a></li>
<li class="toctree-l3"><a class="reference internal" href="#multi-threading-performance">Multi-threading performance</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="errors.html">Error handling</a></li>
<li class="toctree-l2"><a class="reference internal" href="reflection.html">Reflection</a></li>
<li class="toctree-l2"><a class="reference internal" href="programming.html">Writing and running applications</a></li>
<li class="toctree-l2"><a class="reference internal" href="printing.html">Printing messages and asking questions</a></li>
<li class="toctree-l2"><a class="reference internal" href="expansion.html">Term and goal expansion</a></li>
<li class="toctree-l2"><a class="reference internal" href="documenting.html">Documenting</a></li>
<li class="toctree-l2"><a class="reference internal" href="debugging.html">Debugging</a></li>
<li class="toctree-l2"><a class="reference internal" href="performance.html">Performance</a></li>
<li class="toctree-l2"><a class="reference internal" href="installing.html">Installing Logtalk</a></li>
<li class="toctree-l2"><a class="reference internal" href="migration.html">Prolog integration and migration</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../refman/index.html">Reference Manual</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorial/index.html">Tutorial</a></li>
<li class="toctree-l1"><a class="reference internal" href="../faq/index.html">FAQ</a></li>
<li class="toctree-l1"><a class="reference internal" href="../devtools/index.html">Developer Tools</a></li>
<li class="toctree-l1"><a class="reference internal" href="../libraries/index.html">Libraries</a></li>
<li class="toctree-l1"><a class="reference internal" href="../ports/index.html">Ports</a></li>
<li class="toctree-l1"><a class="reference internal" href="../contributions/index.html">Contributions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../glossary.html">Glossary</a></li>
<li class="toctree-l1"><a class="reference internal" href="../bibliography.html">Bibliography</a></li>
<li class="toctree-l1"><a class="reference internal" href="../genindex.html">Index</a></li>
</ul>

    <p class="caption"><span class="caption-text">External Contents</span></p>
    <ul>
    <li class="toctree-l1"><a class="reference internal" href="../../apis/index.html">APIs</a></li>
    <li class="toctree-l1"><a class="reference internal" href="https://logtalk.org">Logtalk website</a></li>
    <li class="toctree-l1"><a class="reference internal" href="https://github.com/LogtalkDotOrg/logtalk3">GitHub repo</a></li>
    </ul>
  
        </div>
      </div>
    </nav>

    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
          <a href="../index.html">The Logtalk Handbook</a>
      </nav>

      <div class="wy-nav-content">
        <div class="rst-content">
          <div role="navigation" aria-label="Page navigation">
  <ul class="wy-breadcrumbs">
      <li><a href="../index.html" class="icon icon-home" aria-label="Home"></a></li>
          <li class="breadcrumb-item"><a href="index.html">User Manual</a></li>
      <li class="breadcrumb-item active">Multi-threading programming</li>
      <li class="wy-breadcrumbs-aside">
              <a href="https://github.com/LogtalkDotOrg/logtalk3/blob/master/docs/handbook/sources/userman/threads.rst" class="fa fa-github"> Edit on GitHub</a>
      </li>
  </ul>
  <hr/>
</div>
          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
           <div itemprop="articleBody">
             
  <section id="multi-threading-programming">
<span id="threads-threads"></span><h1>Multi-threading programming<a class="headerlink" href="#multi-threading-programming" title="Link to this heading"></a></h1>
<p>Logtalk provides <strong>experimental</strong> support for multi-threading programming
on selected Prolog compilers. Logtalk makes use of the low-level Prolog
built-in predicates that implement message queues and interface with POSIX
threads and mutexes (or a suitable emulation), providing a small set of
high-level predicates and directives that allows programmers to easily
take advantage of modern multi-processor and multi-core computers without
worrying about the tricky details of creating, synchronizing, or communicating
with threads, mutexes, and message queues. Logtalk multi-threading
programming integrates with object-oriented programming by providing a
<em>threaded engines</em> API, enabling objects and categories to prove goals
concurrently, and supporting synchronous and asynchronous messages.</p>
<section id="enabling-multi-threading-support">
<span id="threads-enabling"></span><h2>Enabling multi-threading support<a class="headerlink" href="#enabling-multi-threading-support" title="Link to this heading"></a></h2>
<p>Multi-threading support may be disabled by default. It can be enabled on
the Prolog adapter files of supported compilers by setting the read-only
<a class="reference internal" href="programming.html#flag-threads"><span class="std std-ref">threads</span></a> compiler flag to <code class="docutils literal notranslate"><span class="pre">supported</span></code>.</p>
</section>
<section id="enabling-objects-to-make-multi-threading-calls">
<span id="threads-directive"></span><h2>Enabling objects to make multi-threading calls<a class="headerlink" href="#enabling-objects-to-make-multi-threading-calls" title="Link to this heading"></a></h2>
<p>The <a class="reference internal" href="../refman/directives/threaded_0.html#directives-threaded-0"><span class="std std-ref">threaded/0</span></a> object
directive is used to enable an object to make multi-threading calls:</p>
<div class="highlight-logtalk notranslate"><div class="highlight"><pre><span></span><span class="p">:- </span><span class="k">threaded</span>.
</pre></div>
</div>
</section>
<section id="multi-threading-built-in-predicates">
<span id="threads-predicates"></span><h2>Multi-threading built-in predicates<a class="headerlink" href="#multi-threading-built-in-predicates" title="Link to this heading"></a></h2>
<p>Logtalk provides a small set of built-in predicates for multi-threading
programming. For simple tasks where you simply want to prove a set of
goals, each one in its own thread, Logtalk provides a
<a class="reference internal" href="../refman/predicates/threaded_1.html#predicates-threaded-1"><span class="std std-ref">threaded/1</span></a> built-in
predicate. The remaining predicates allow for fine-grained control,
including postponing retrieval of thread goal results at a later time,
supporting non-deterministic thread goals, and making <em>one-way</em>
asynchronous calls. Together, these predicates provide high-level
support for multi-threading programming, covering most common use cases.</p>
<section id="proving-goals-concurrently-using-threads">
<span id="threads-threaded"></span><h3>Proving goals concurrently using threads<a class="headerlink" href="#proving-goals-concurrently-using-threads" title="Link to this heading"></a></h3>
<p>A set of goals may be proved concurrently by calling the Logtalk
built-in predicate <a class="reference internal" href="../refman/predicates/threaded_1.html#predicates-threaded-1"><span class="std std-ref">threaded/1</span></a>. Each goal in
the set runs in its own thread.</p>
<p>When the <code class="docutils literal notranslate"><span class="pre">threaded/1</span></code> predicate argument is a <em>conjunction</em> of goals,
the predicate call is akin to <em>and-parallelism</em>. For example, assume
that we want to find all the prime numbers in a given interval,
<code class="docutils literal notranslate"><span class="pre">[N,</span> <span class="pre">M]</span></code>. We can split the interval into two parts and then span two
threads to compute the prime numbers in each sub-interval:</p>
<div class="highlight-logtalk notranslate"><div class="highlight"><pre><span></span>prime_numbers(<span class="nv">N</span>, <span class="nv">M</span>, <span class="nv">Primes</span>) <span class="o">:-</span>
    <span class="nv">M</span> <span class="o">&gt;</span> <span class="nv">N</span>,
    <span class="nv">N1</span> <span class="k">is</span> <span class="nv">N</span> <span class="o">+</span> (<span class="nv">M</span> <span class="o">-</span> <span class="nv">N</span>) <span class="o">//</span> <span class="m">2</span>,
    <span class="nv">N2</span> <span class="k">is</span> <span class="nv">N1</span> <span class="o">+</span> <span class="m">1</span>,
    <span class="k">threaded</span>((
        prime_numbers(<span class="nv">N2</span>, <span class="nv">M</span>, [], <span class="nv">Acc</span>),
        prime_numbers(<span class="nv">N</span>, <span class="nv">N1</span>, <span class="nv">Acc</span>, <span class="nv">Primes</span>)
    )).

prime_numbers(<span class="nv">N</span>, <span class="nv">M</span>, <span class="nv">Acc</span>, <span class="nv">Primes</span>) <span class="o">:-</span>
    ...
</pre></div>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">threaded/1</span></code> call terminates when the two implicit threads
terminate. In a computer with two or more processors (or with a
processor with two or more cores), the code above can be expected to
provide better computation times when compared with single-threaded code
for sufficiently large intervals.</p>
<p>When the <code class="docutils literal notranslate"><span class="pre">threaded/1</span></code> predicate argument is a <em>disjunction</em> of goals,
the predicate call is akin to <em>or-parallelism</em>, here reinterpreted as a
set of goals <em>competing</em> to find a solution. For example, consider the
different methods that we can use to find the roots of real functions.
Depending on the function, some methods will be faster than others. Some
methods will converge to the solution while others may diverge and
never find it. We can try all the methods simultaneously by writing:</p>
<div class="highlight-logtalk notranslate"><div class="highlight"><pre><span></span>find_root(<span class="nv">Function</span>, <span class="nv">A</span>, <span class="nv">B</span>, <span class="nv">Error</span>, <span class="nv">Zero</span>) <span class="o">:-</span>
    <span class="k">threaded</span>((
        bisection<span class="o">::</span>find_root(<span class="nv">Function</span>, <span class="nv">A</span>, <span class="nv">B</span>, <span class="nv">Error</span>, <span class="nv">Zero</span>)
    <span class="o">;</span>   newton<span class="o">::</span>find_root(<span class="nv">Function</span>, <span class="nv">A</span>, <span class="nv">B</span>, <span class="nv">Error</span>, <span class="nv">Zero</span>)
    <span class="o">;</span>   muller<span class="o">::</span>find_root(<span class="nv">Function</span>, <span class="nv">A</span>, <span class="nv">B</span>, <span class="nv">Error</span>, <span class="nv">Zero</span>)
    )).
</pre></div>
</div>
<p>The above <code class="docutils literal notranslate"><span class="pre">threaded/1</span></code> goal succeeds when one of the implicit threads
succeeds in finding the function root, leading to the termination of all
the remaining competing threads.</p>
<p>The <code class="docutils literal notranslate"><span class="pre">threaded/1</span></code> built-in predicate is most useful for lengthy,
independent, deterministic computations where the computational costs of
each goal outweigh the overhead of the implicit thread creation and
management.</p>
</section>
<section id="proving-goals-asynchronously-using-threads">
<span id="threads-call"></span><h3>Proving goals asynchronously using threads<a class="headerlink" href="#proving-goals-asynchronously-using-threads" title="Link to this heading"></a></h3>
<p>A goal may be proved asynchronously using a new thread by calling the
<a class="reference internal" href="../refman/predicates/threaded_call_1_2.html#predicates-threaded-call-1-2"><span class="std std-ref">threaded_call/1-2</span></a> built-in predicate .
Calls to this predicate are always true and return immediately (assuming
a callable argument). The term representing the goal is copied, not
shared with the thread. The thread computes the first solution to the
goal, posts it to the implicit message queue of the object from where the
<code class="docutils literal notranslate"><span class="pre">threaded_call/1</span></code> predicate was called, and suspends waiting for
either a request for an alternative solution or for the program to
commit to the current solution.</p>
<p>The results of proving a goal asynchronously in a new thread may be
later retrieved by calling the <a class="reference internal" href="../refman/predicates/threaded_exit_1_2.html#predicates-threaded-exit-1-2"><span class="std std-ref">threaded_exit/1-2</span></a>
built-in predicate within the same object where the call to the
<code class="docutils literal notranslate"><span class="pre">threaded_call/1</span></code> predicate was made. The <code class="docutils literal notranslate"><span class="pre">threaded_exit/1</span></code>
calls suspend execution until the results of the <code class="docutils literal notranslate"><span class="pre">threaded_call/1</span></code>
calls are sent back to the object message queue.</p>
<p>The <code class="docutils literal notranslate"><span class="pre">threaded_exit/1</span></code> predicate allows us to retrieve alternative
solutions through backtracking (if you want to commit to the first
solution, you may use the <a class="reference internal" href="../refman/predicates/threaded_once_1_2.html#predicates-threaded-once-1-2"><span class="std std-ref">threaded_once/1-2</span></a>
predicate instead of the <code class="docutils literal notranslate"><span class="pre">threaded_call/1</span></code> predicate). For example,
assuming a <code class="docutils literal notranslate"><span class="pre">lists</span></code> object implementing the usual <code class="docutils literal notranslate"><span class="pre">member/2</span></code>
predicate, we could write:</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>| ?- threaded_call(lists::member(X, [1,2,3])).

X = _G189
yes

| ?- threaded_exit(lists::member(X, [1,2,3])).

X = 1 ;
X = 2 ;
X = 3 ;
no
</pre></div>
</div>
<p>In this case, the <code class="docutils literal notranslate"><span class="pre">threaded_call/1</span></code> and the <code class="docutils literal notranslate"><span class="pre">threaded_exit/1</span></code> calls
are made within the pseudo-object <code class="docutils literal notranslate"><span class="pre">user</span></code>. The implicit thread running
the <code class="docutils literal notranslate"><span class="pre">lists::member/2</span></code> goal suspends itself after providing a solution,
waiting for a request for an alternative solution; the thread is
automatically terminated when the runtime engine detects that
backtracking to the <code class="docutils literal notranslate"><span class="pre">threaded_exit/1</span></code> call is no longer possible.</p>
<p>Calls to the <code class="docutils literal notranslate"><span class="pre">threaded_exit/1</span></code> predicate block the caller until the
object message queue receives the reply to the asynchronous call. The
predicate <a class="reference internal" href="../refman/predicates/threaded_peek_1_2.html#predicates-threaded-peek-1-2"><span class="std std-ref">threaded_peek/1-2</span></a>
may be used to check if a reply is already available without removing it
from the thread queue. The <code class="docutils literal notranslate"><span class="pre">threaded_peek/1</span></code> predicate call succeeds
or fails immediately without blocking the caller. However, keep in mind
that repeated use of this predicate is equivalent to polling a message
queue, which may hurt performance.</p>
<p>Be careful when using the <code class="docutils literal notranslate"><span class="pre">threaded_exit/1</span></code> predicate inside
failure-driven loops. When all the solutions have been found (and the
thread generating them is therefore terminated), re-calling the
predicate will generate an exception. Note that failing instead of
throwing an exception is not an acceptable solution, as it could be
misinterpreted as a failure of the <code class="docutils literal notranslate"><span class="pre">threaded_call/1</span></code> argument.</p>
<p>The example in the previous section with prime numbers could be
rewritten using the <code class="docutils literal notranslate"><span class="pre">threaded_call/1</span></code> and <code class="docutils literal notranslate"><span class="pre">threaded_exit/1</span></code>
predicates:</p>
<div class="highlight-logtalk notranslate"><div class="highlight"><pre><span></span>prime_numbers(<span class="nv">N</span>, <span class="nv">M</span>, <span class="nv">Primes</span>) <span class="o">:-</span>
    <span class="nv">M</span> <span class="o">&gt;</span> <span class="nv">N</span>,
    <span class="nv">N1</span> <span class="k">is</span> <span class="nv">N</span> <span class="o">+</span> (<span class="nv">M</span> <span class="o">-</span> <span class="nv">N</span>) <span class="o">//</span> <span class="m">2</span>,
    <span class="nv">N2</span> <span class="k">is</span> <span class="nv">N1</span> <span class="o">+</span> <span class="m">1</span>,
    <span class="k">threaded_call</span>(prime_numbers(<span class="nv">N2</span>, <span class="nv">M</span>, [], <span class="nv">Acc</span>)),
    <span class="k">threaded_call</span>(prime_numbers(<span class="nv">N</span>, <span class="nv">N1</span>, <span class="nv">Acc</span>, <span class="nv">Primes</span>)),
    <span class="k">threaded_exit</span>(prime_numbers(<span class="nv">N2</span>, <span class="nv">M</span>, [], <span class="nv">Acc</span>)),
    <span class="k">threaded_exit</span>(prime_numbers(<span class="nv">N</span>, <span class="nv">N1</span>, <span class="nv">Acc</span>, <span class="nv">Primes</span>)).

prime_numbers(<span class="nv">N</span>, <span class="nv">M</span>, <span class="nv">Acc</span>, <span class="nv">Primes</span>) <span class="o">:-</span>
    ...
</pre></div>
</div>
<p>When using asynchronous calls, the link between a <code class="docutils literal notranslate"><span class="pre">threaded_exit/1</span></code>
call and the corresponding <code class="docutils literal notranslate"><span class="pre">threaded_call/1</span></code> call is established using
unification. If there are multiple <code class="docutils literal notranslate"><span class="pre">threaded_call/1</span></code> calls for a matching
<code class="docutils literal notranslate"><span class="pre">threaded_exit/1</span></code> call, the connection can potentially be established with
any of them (this is akin to what happens with tabling). Nevertheless, you
can easily use a call <em>tag</em> by using the
alternative <a class="reference internal" href="../refman/predicates/threaded_call_1_2.html#predicates-threaded-call-1-2"><span class="std std-ref">threaded_call/2</span></a>,
<a class="reference internal" href="../refman/predicates/threaded_once_1_2.html#predicates-threaded-once-1-2"><span class="std std-ref">threaded_once/2</span></a>, and
<a class="reference internal" href="../refman/predicates/threaded_exit_1_2.html#predicates-threaded-exit-1-2"><span class="std std-ref">threaded_exit/2</span></a> built-in predicates.
For example:</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>?- threaded_call(member(X, [1,2,3]), Tag).

Tag = 1
yes

?- threaded_call(member(X, [1,2,3]), Tag).

Tag = 2
yes

?- threaded_exit(member(X, [1,2,3]), 2).

X = 1 ;
X = 2 ;
X = 3
yes
</pre></div>
</div>
<p>When using these predicates, the tags shall be considered as an opaque
term; users shall not rely on its type. Tagged asynchronous calls can be
canceled by using the <a class="reference internal" href="../refman/predicates/threaded_cancel_1.html#predicates-threaded-cancel-1"><span class="std std-ref">threaded_cancel/1</span></a> predicate.</p>
</section>
</section>
<section id="one-way-asynchronous-calls">
<span id="threads-ignore"></span><h2>One-way asynchronous calls<a class="headerlink" href="#one-way-asynchronous-calls" title="Link to this heading"></a></h2>
<p>Sometimes we want to prove a goal in a new thread without caring about
the results. This may be accomplished by using the built-in predicate
<a class="reference internal" href="../refman/predicates/threaded_ignore_1.html#predicates-threaded-ignore-1"><span class="std std-ref">threaded_ignore/1</span></a>.
For example, assume that we are developing a multi-agent application
where an agent may send a “happy birthday” message to another agent. We
could write:</p>
<div class="highlight-logtalk notranslate"><div class="highlight"><pre><span></span>..., <span class="k">threaded_ignore</span>(agent<span class="o">::</span>happy_birthday), ...
</pre></div>
</div>
<p>The call succeeds with no reply of the goal success, failure, or even
exception ever being sent back to the object making the call. Note that
this predicate implicitly performs a deterministic call of its argument.</p>
</section>
<section id="asynchronous-calls-and-synchronized-predicates">
<span id="threads-synchronized-predicates"></span><h2>Asynchronous calls and synchronized predicates<a class="headerlink" href="#asynchronous-calls-and-synchronized-predicates" title="Link to this heading"></a></h2>
<p>Proving a goal asynchronously using a new thread may lead to problems
when the goal results in side effects such as input/output operations or
modifications to an <a class="reference internal" href="../glossary.html#term-object-database"><span class="xref std std-term">object database</span></a>. For example, if a new thread is
started with the same goal before the first one finished its job, we may
end up with mixed output, a corrupted database, or unexpected goal
failures. In order to solve this problem, predicates (and grammar rule
non-terminals) with side effects can be declared as <em>synchronized</em> by
using the <a class="reference internal" href="../refman/directives/synchronized_1.html#directives-synchronized-1"><span class="std std-ref">synchronized/1</span></a>
predicate directive. Proving a query to a synchronized predicate (or
synchronized non-terminal) is internally protected by a mutex, thus
allowing for easy thread synchronization. For example:</p>
<div class="highlight-logtalk notranslate"><div class="highlight"><pre><span></span><span class="c">% ensure thread synchronization</span>
<span class="p">:- </span><span class="k">synchronized</span>(db_update<span class="o">/</span><span class="m">1</span>).

db_update(<span class="nv">Update</span>) <span class="o">:-</span>
    <span class="c">% predicate with side-effects</span>
    ...
</pre></div>
</div>
<p>A second example: assume an object defining two predicates for writing,
respectively, even and odd numbers in a given interval to the standard
output. Given a large interval, a goal such as:</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>| ?- threaded_call(obj::odd_numbers(1,100)),
     threaded_call(obj::even_numbers(1,100)).

1 3 2 4 6 8 5 7 10 ...
...
</pre></div>
</div>
<p>will most likely result in a mixed-up output. By declaring the
<code class="docutils literal notranslate"><span class="pre">odd_numbers/2</span></code> and <code class="docutils literal notranslate"><span class="pre">even_numbers/2</span></code> predicates synchronized:</p>
<div class="highlight-logtalk notranslate"><div class="highlight"><pre><span></span><span class="p">:- </span><span class="k">synchronized</span>([
    odd_numbers<span class="o">/</span><span class="m">2</span>,
    even_numbers<span class="o">/</span><span class="m">2</span>]).
</pre></div>
</div>
<p>one goal will only start after the other one finished:</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>| ?- threaded_ignore(obj::odd_numbers(1,99)),
     threaded_ignore(obj::even_numbers(1,99)).

1 3 5 7 9 11 ...
...
2 4 6 8 10 12 ...
...
</pre></div>
</div>
<p>Note that, in a more realistic scenario, the two <code class="docutils literal notranslate"><span class="pre">threaded_ignore/1</span></code>
calls would be made concurrently from different objects. Using the same
synchronized directive for a set of predicates implies that they all use
the same mutex, as required for this example.</p>
<p>As each Logtalk entity is independently compiled, this directive must be
included in every object or category that contains a definition for the
described predicate, even if the predicate declaration is inherited from
another entity, in order to ensure proper compilation. Note that a
synchronized predicate cannot be declared dynamic. To ensure atomic
updates of a dynamic predicate, declare as synchronized the predicate
performing the update.</p>
<p>Synchronized predicates may be used as wrappers for messages sent to
objects that are not multi-threading aware. For example, assume a
<code class="docutils literal notranslate"><span class="pre">log</span></code> object defining a <code class="docutils literal notranslate"><span class="pre">write_log_entry/2</span></code> predicate that writes
log entries to a file, thus using side effects on its implementation.
We can specify and define, for example, a <code class="docutils literal notranslate"><span class="pre">sync_write_log_entry/2</span></code>
predicate as follows:</p>
<div class="highlight-logtalk notranslate"><div class="highlight"><pre><span></span><span class="p">:- </span><span class="k">synchronized</span>(sync_write_log_entry<span class="o">/</span><span class="m">2</span>).

sync_write_log_entry(<span class="nv">File</span>, <span class="nv">Entry</span>) <span class="o">:-</span>
    log<span class="o">::</span>write_log_entry(<span class="nv">File</span>, <span class="nv">Entry</span>).
</pre></div>
</div>
<p>and then call the <code class="docutils literal notranslate"><span class="pre">sync_write_log_entry/2</span></code> predicate instead of the
<code class="docutils literal notranslate"><span class="pre">write_log_entry/2</span></code> predicate from multi-threaded code.</p>
<p>The synchronization directive may be used when defining objects that may be
reused in both single-threaded and multi-threaded Logtalk applications. The
directive simply makes calls to the synchronized predicates deterministic
when the objects are used in a single-threaded application.</p>
</section>
<section id="synchronizing-threads-through-notifications">
<span id="threads-notifications"></span><h2>Synchronizing threads through notifications<a class="headerlink" href="#synchronizing-threads-through-notifications" title="Link to this heading"></a></h2>
<p>Declaring a set of predicates as synchronized can only ensure that they
are not executed at the same time by different threads. Sometimes we
need to suspend a thread not on a synchronization lock but on some
condition that must hold true for a thread goal to proceed. I.e. we want
a thread goal to be suspended until a condition becomes true instead of
simply failing. The built-in predicate <a class="reference internal" href="../refman/predicates/threaded_wait_1.html#predicates-threaded-wait-1"><span class="std std-ref">threaded_wait/1</span></a>
allows us to suspend a predicate execution (running in its own thread)
until a notification is received. Notifications are posted using the
built-in predicate <a class="reference internal" href="../refman/predicates/threaded_notify_1.html#predicates-threaded-notify-1"><span class="std std-ref">threaded_notify/1</span></a>.
A notification is a Prolog term that a programmer chooses to represent
some condition becoming true. Any Prolog term can be used as a
notification argument for these predicates. Related calls to the
<code class="docutils literal notranslate"><span class="pre">threaded_wait/1</span></code> and <code class="docutils literal notranslate"><span class="pre">threaded_notify/1</span></code> must be made within the
same object, <em>this</em>, as the object message queue is used internally for
posting and retrieving notifications.</p>
<p>Each notification posted by a call to the <code class="docutils literal notranslate"><span class="pre">threaded_notify/1</span></code>
predicate is consumed by a single <code class="docutils literal notranslate"><span class="pre">threaded_wait/1</span></code> predicate call
(i.e., these predicates implement a peer-to-peer mechanism). Care should
be taken to avoid deadlocks when two (or more) threads both wait and
post notifications to each other.</p>
</section>
<section id="threaded-engines">
<span id="threads-engines"></span><h2>Threaded engines<a class="headerlink" href="#threaded-engines" title="Link to this heading"></a></h2>
<p>Threaded engines provide an alternative to the multi-threading
predicates described in the previous sections. An <em>engine</em> is a computing
thread whose solutions can be lazily computed and retrieved. In
addition, an engine also supports a term queue that allows passing
arbitrary terms to the engine.</p>
<p>An engine is created by calling the <a class="reference internal" href="../refman/predicates/threaded_engine_create_3.html#predicates-threaded-engine-create-3"><span class="std std-ref">threaded_engine_create/3</span></a>
built-in predicate. For example:</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>| ?- threaded_engine_create(X, member(X, [1,2,3]), worker).
yes
</pre></div>
</div>
<p>The first argument is an <em>answer template</em> to be used for retrieving
solution bindings. The user can name the engine, as in this example
where the atom <code class="docutils literal notranslate"><span class="pre">worker</span></code> is used, or have the runtime generate a name,
which should be treated as an opaque term.</p>
<p>Engines are scoped by the object within which the
<code class="docutils literal notranslate"><span class="pre">threaded_engine_create/3</span></code> call takes place. Thus, different objects
can create engines with the same names with no conflicts. Moreover,
engines share the visible predicates of the object creating them.</p>
<p>The engine computes the first solution of its goal argument and suspends
waiting for it to be retrieved. Solutions can be retrieved one at a time
using the <a class="reference internal" href="../refman/predicates/threaded_engine_next_2.html#predicates-threaded-engine-next-2"><span class="std std-ref">threaded_engine_next/2</span></a> built-in predicate:</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>| ?- threaded_engine_next(worker, X).
X = 1
yes
</pre></div>
</div>
<p>The call blocks until a solution is available and fails if there are no
solutions left. After returning a solution, this predicate signals the
engine to start computing the next one. Note that this predicate is
deterministic. In contrast with the <code class="docutils literal notranslate"><span class="pre">threaded_exit/1-2</span></code> built-in
predicates, retrieving the next solution requires calling the predicate
again instead of backtracking into its call. For example:</p>
<div class="highlight-logtalk notranslate"><div class="highlight"><pre><span></span>collect_all(<span class="nv">Engine</span>, [<span class="nv">Answer</span>| <span class="nv">Answers</span>]) <span class="o">:-</span>
    <span class="k">threaded_engine_next</span>(<span class="nv">Engine</span>, <span class="nv">Answer</span>),
    <span class="o">!</span>,
    collect_all(<span class="nv">Engine</span>, <span class="nv">Answers</span>).
collect_all(<span class="nv">_</span>, []).
</pre></div>
</div>
<p>There is also a reified alternative version of the predicate,
<a class="reference internal" href="../refman/predicates/threaded_engine_next_reified_2.html#predicates-threaded-engine-next-reified-2"><span class="std std-ref">threaded_engine_next_reified/2</span></a>,
which returns <code class="docutils literal notranslate"><span class="pre">the(Answer)</span></code>, <code class="docutils literal notranslate"><span class="pre">no</span></code>, and <code class="docutils literal notranslate"><span class="pre">exception(Error)</span></code> terms as
answers. Using this predicate, collecting all solutions to an engine
uses a different programming pattern:</p>
<div class="highlight-logtalk notranslate"><div class="highlight"><pre><span></span>... <span class="o">:-</span>
    ...,
    <span class="k">threaded_engine_next_reified</span>(<span class="nv">Engine</span>, <span class="nv">Reified</span>),
    collect_all_reified(<span class="nv">Reified</span>, <span class="nv">Engine</span>, <span class="nv">Answers</span>),
    ...

collect_all_reified(no, <span class="nv">_</span>, []).
collect_all_reified(the(<span class="nv">Answer</span>), <span class="nv">Engine</span>, [<span class="nv">Answer</span>| <span class="nv">Answers</span>]) <span class="o">:-</span>
    <span class="k">threaded_engine_next_reified</span>(<span class="nv">Engine</span>, <span class="nv">Reified</span>),
    collect_all_reified(<span class="nv">Reified</span>, <span class="nv">Engine</span>, <span class="nv">Answers</span>).
</pre></div>
</div>
<p>Engines must be explicitly terminated using the
<a class="reference internal" href="../refman/predicates/threaded_engine_destroy_1.html#predicates-threaded-engine-destroy-1"><span class="std std-ref">threaded_engine_destroy/1</span></a> built-in predicate:</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>| ?- threaded_engine_destroy(worker).
yes
</pre></div>
</div>
<p>A common usage pattern for engines is to define a recursive predicate
that uses the engine term queue to retrieve a task to be performed. For
example, assume we define the following predicate:</p>
<div class="highlight-logtalk notranslate"><div class="highlight"><pre><span></span>loop <span class="o">:-</span>
    <span class="k">threaded_engine_fetch</span>(<span class="nv">Task</span>),
    handle(<span class="nv">Task</span>),
    loop.
</pre></div>
</div>
<p>The <a class="reference internal" href="../refman/predicates/threaded_engine_fetch_1.html#predicates-threaded-engine-fetch-1"><span class="std std-ref">threaded_engine_fetch/1</span></a>
built-in predicate fetches a task for the engine term queue. The engine
clients would use the <a class="reference internal" href="../refman/predicates/threaded_engine_post_2.html#predicates-threaded-engine-post-2"><span class="std std-ref">threaded_engine_post/2</span></a>
built-in predicate to post tasks into the engine term queue. The engine
would be created using the call:</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>| ?- threaded_engine_create(none, loop, worker).

yes
</pre></div>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">handle/1</span></code> predicate, after performing a task, can use the
<a class="reference internal" href="../refman/predicates/threaded_engine_yield_1.html#predicates-threaded-engine-yield-1"><span class="std std-ref">threaded_engine_yield/1</span></a> built-in predicate to make the
task results available for consumption using the <code class="docutils literal notranslate"><span class="pre">threaded_engine_next/2</span></code>
and <code class="docutils literal notranslate"><span class="pre">threaded_engine_next_reified/2</span></code> built-in predicates. Blocking
semantics are used by these two predicates: the <code class="docutils literal notranslate"><span class="pre">threaded_engine_yield/1</span></code>
predicate blocks until the returned solution is consumed, while the
<code class="docutils literal notranslate"><span class="pre">threaded_engine_next/2</span></code> predicate blocks until a solution becomes
available.</p>
</section>
<section id="multi-threading-performance">
<span id="threads-performance"></span><h2>Multi-threading performance<a class="headerlink" href="#multi-threading-performance" title="Link to this heading"></a></h2>
<p>The performance of multi-threading applications is highly dependent on
the <a class="reference internal" href="../glossary.html#term-backend-Prolog-compiler"><span class="xref std std-term">backend Prolog compiler</span></a>, the operating-system, and the use
of <a class="reference internal" href="../glossary.html#term-dynamic-binding"><span class="xref std std-term">dynamic binding</span></a> and dynamic predicates. All compatible backend
Prolog compilers that support multi-threading features make use of POSIX
threads or <em>pthreads</em>. The performance of the underlying pthreads
implementation can exhibit significant differences between operating
systems. An important point is synchronized access to dynamic
predicates. As different threads may try to simultaneously access and
update dynamic predicates, these operations may use a lock-free algorithm
or be protected by a lock, usually implemented using a mutex. In the latter
case, poor mutex lock operating-system performance, combined with a large
number of collisions by several threads trying to acquire the same lock,
can result in severe performance penalties. Thus, whenever possible,
avoid using dynamic predicates and dynamic binding.</p>
</section>
</section>


           </div>
          </div>
          <footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
        <a href="events.html" class="btn btn-neutral float-left" title="Event-driven programming" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
        <a href="errors.html" class="btn btn-neutral float-right" title="Error handling" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
    </div>

  <hr/>

  <div role="contentinfo">
    <p>&#169; Copyright 1998-2025, Paulo Moura.</p>
  </div>

  Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
    <a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
    provided by <a href="https://readthedocs.org">Read the Docs</a>.
   

</footer>
        </div>
      </div>
    </section>
  </div>
  <script>
      jQuery(function () {
          SphinxRtdTheme.Navigation.enable(true);
      });
  </script> 

</body>
</html>